(define-module (metrics))


(use-modules
 (dataset))


(define-public accuracy-metric
  (lambda (actual-labels predicted-labels)
    ;; assumption: actual-labels and predicted-labels have the same length
    (let iter ([remaining-actual-labels actual-labels]
               [remaining-predicted-labels predicted-labels]
               [labels-count 0]
               [correct-labels-count 0])
      (cond
       ;; TODO: Should this not be a column abstraction predicate instead of
       ;; ~null?~?
       [(dataset-column-empty? remaining-actual-labels)
        (/ correct-labels-count labels-count)]
       [else
        ;; TODO: For the predicted labels we might also want to use dataset
        ;; astractions, because it is a result of ~dataset-map~, but on the
        ;; other hand, it seems weird to think of the returned predictions as a
        ;; dataset. Perhaps we can rewrite it to be a column of a dataset
        ;; instead.
        (if (= (dataset-column-first remaining-actual-labels)
               (car remaining-predicted-labels))
            (iter (dataset-column-rest remaining-actual-labels)
                  (cdr remaining-predicted-labels)
                  (+ labels-count 1)
                  (+ correct-labels-count 1))
            (iter (dataset-column-rest remaining-actual-labels)
                  (cdr remaining-predicted-labels)
                  (+ labels-count 1)
                  correct-labels-count))]))))
